<!--
 * @Author: caihongtai caihongtai
 * @Date: 2025-02-08 21:23:44
 * @LastEditors: caihongtai caihongtai
 * @LastEditTime: 2025-03-27 10:21:33
 * @FilePath: /ai-interview-vue/src/views/Interview/index.vue
 * @Description: WebSocket测试页面
-->
<template>
    <div class="interview">
        <!-- 输入区域 -->
        <div>
            <button @click="wsConnection">连接</button>
            <input type="text" v-model="interviewId" placeholder="请输入会话ID">
            <input type="text" v-model="token" placeholder="请输入token">
        </div>
        <div>
            <audio ref="ttsPlayer" controls></audio>
        </div>
    </div>
</template>

<script setup>
    import { ref } from 'vue'

    const interviewId = ref('5')
    const token = ref('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNzQyODg1Nzg0LCJpYXQiOjE3NDIyODA5ODQsImp0aSI6IjZiOTVhYmZhNmVlODRhMDRhN2I1MGNmMjkwZjFjNjMyIiwidXNlcl9pZCI6MX0.IfS_QI1fgNDCd4fVY7YzfX6JLLohK4XrBkG3ObT4d2U')
    const ttsPlayer = ref(null)

    let ws
    let audioContext
    let input
    let processor
    let accumulatedData = []
    const sampleRate = 16000
    const bufferSize = 4096
    let isAudioPlaying = false
    let sendInterval

    const wsConnection = async () => {
        try {
            // 1. 先获取音频设备权限
            const stream = await navigator.mediaDevices.getUserMedia({
                audio: {
                    channelCount: 1,           // 单声道
                    sampleRate: sampleRate,    // 采样率16000Hz
                    echoCancellation: true,    // 开启回声消除
                    noiseSuppression: true     // 开启降噪
                }
            })

            // 设置音频处理
            audioContext = new AudioContext({
                sampleRate: sampleRate,        // 设置音频上下文的采样率
                latencyHint: 'interactive'
            })

            input = audioContext.createMediaStreamSource(stream)
            processor = audioContext.createScriptProcessor(bufferSize, 1, 1)

            input.connect(processor)
            processor.connect(audioContext.destination)

            // 处理音频数据
            processor.onaudioprocess = (e) => {
                if (ws && ws.readyState === WebSocket.OPEN && !isAudioPlaying) {
                    const inputData = e.inputBuffer.getChannelData(0)
                    const pcmData = new Int16Array(inputData.length)
                    for (let i = 0; i < inputData.length; i++) {
                        pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 0x7FFF))
                    }
                    // Just accumulate data
                    accumulatedData.push(...pcmData)
                }
            }

            // 2. 开始连接后端 ws 接口
            ws = new WebSocket('wss://ointerview.com/ws/conversation?token=' + token.value)

            ws.onopen = function () {
                console.log('连接成功')
                ws.send(JSON.stringify({ "operation_type": "start", "interview_id": interviewId.value }))

                // Start sending data at 1-second intervals
                sendInterval = setInterval(() => {
                    if (ws && ws.readyState === WebSocket.OPEN && !isAudioPlaying && accumulatedData.length > 0) {
                        // Send approximately 1 second of audio data
                        const dataToSend = accumulatedData.slice(0, sampleRate)
                        ws.send(new Int16Array(dataToSend).buffer)
                        accumulatedData = accumulatedData.slice(Math.min(sampleRate, accumulatedData.length))
                        console.log("Sent 1 second of audio data")
                    }
                }, 1000)
            }

            ws.onmessage = function (e) {
                console.log('收到消息：', e.data)
                const data = JSON.parse(e.data)
                if (data.code === 0 && data.data && data.data.question_url) {
                    ttsPlayer.value.src = data.data.question_url
                    ttsPlayer.value.play()
                }
            }

            ws.onclose = function () {
                console.log('连接关闭')
                clearInterval(sendInterval)
            }

            ws.onerror = function () {
                console.log('连接出错')
            }

        } catch (error) {
            console.error('获取音频设备权限失败:', error)
        }
    }
    const cleanup = () => {

        if (sendInterval) {
            clearInterval(sendInterval)
            sendInterval = null
        }

        if (ws) {
            ws.close()
            ws = null
        }

        if (processor) {
            processor.disconnect()
            processor = null
        }

        if (input) {
            input.disconnect()
            input = null
        }

        if (audioContext) {
            audioContext.close()
            audioContext = null
        }

        accumulatedData = []
        isAudioPlaying = false

    }
    onMounted(() => {
        wsConnection()
    })
    onBeforeUnmount(() => {
        cleanup()
    })
</script>

<style lang="scss" scoped>
    .interview {
        padding: 16px;
    }
</style>